<script lang="ts" setup>
import { isEmpty } from '@vben/utils';

import { InputSearch, Select, Table, TreeSelect } from 'ant-design-vue';

import { useDatasourceStore } from '#/store';

type Key = number | string;
// 接收父组件传递的属性和事件
defineOptions({
  name: 'DataSourceSelect',
});
const props = withDefaults(
  defineProps<{
    dataSource: {
      api: string;
      filters?: object;
      multi: boolean;
    };
    options?: any;
    placeholder?: string;
    value?: any;
  }>(),
  {
    dataSource: () => ({
      api: '',
      multi: false,
      filters: {},
    }),
    placeholder: '',
    value: undefined,
    options: undefined,
  },
);
// emit 用于通知父组件更新值
const emit = defineEmits<{
  (e: 'update:value', value: any): void;
}>();
const api = ref(props.dataSource.api.toLowerCase());
const selectValue: any = ref(null);
const treeData = ref<any>([]);
// 将值转换为数字数组
const convertToNumberArray = (value: any) => {
  if (Array.isArray(value)) {
    // 如果是数组，转换数组中的每个元素为数字
    return value.map(Number);
  }
  // 如果是单个字符串，直接转换成数字
  return [Number(value)];
};

const fieldNames = ref<any>();

// 确保 value 是数组
const handleValue = (value: any) => {
  return Array.isArray(value) ? value : [value]; // 如果不是数组，转化为数组
};

const onSelect = (value: any) => {
  try {
    // 确保 value 是数组，处理单选和多选场景
    const currentValue = handleValue(props.value);

    let updataValue = props.dataSource.multi
      ? [...new Set([...currentValue, ...handleValue(value)])] // Multi-select logic
      : value; // Single-select logic
    if (props.dataSource.multi)
      updataValue = updataValue.filter((item: any) => !isEmpty(item)); // 防止传入空数据
    emit('update:value', updataValue); // 发射更新事件给父组件
  } catch (error) {
    console.error('Error in onSelect handler:', error);
  }
};
const state = reactive<{
  loading: boolean;
  searchQuery: string;
  selectedRowKeys: Key[];
  selectedRows: any[];
  selectValue: any[];
}>({
  selectedRowKeys: [], // Check here to configure the default column
  loading: false,
  selectedRows: [],
  searchQuery: '',
  selectValue: [],
});
const columns = ref([
  {
    title: '编码',
    dataIndex: 'id',
    key: 'id',
  },
  {
    title: '标题',
    dataIndex: 'post_title',
    key: 'post_title',
  },
  {
    title: '发布时间',
    dataIndex: 'published_time',
    key: 'published_time',
  },
]);

const pagination = ref({
  current: 1,
  pageSize: 10,
  total: 0, // 假设总共有50条数据
  showSizeChanger: false,
});

// 获取数据
const fetchData = async () => {
  // 获取数据
  const { data } = useDatasourceStore().getdataSource(
    props.dataSource.api.toLowerCase(),
    {
      filters: {
        keyword: state.searchQuery,
        page: pagination.value.current,
      },
    },
  );
  treeData.value = await data;
  pagination.value.total =
    treeData.value.length < pagination.value.pageSize
      ? pagination.value.pageSize - 1
      : pagination.value.pageSize + 1;
};
/** 表格选择分页 */
const handleTableChange = (changePagination: any) => {
  pagination.value.current = changePagination.current;
  fetchData();
};
/** 表格选择数据 */
const rowSelection = ref({
  onChange: (newSelectedRowKeys: any[], selectedRowsData: any[]) => {
    // 处理选择和取消选择
    state.selectedRowKeys = [
      ...new Set([...newSelectedRowKeys, ...state.selectedRowKeys]),
    ];
    state.selectedRows = [
      ...new Set([...selectedRowsData, ...state.selectedRows]),
    ];

    // 更新Select的值为选中的行的数据（例如选中的行的名称）
    state.selectValue = state.selectedRows.map((row) => row.id);
  },
  onSelect: (record: any, selected: any) => {
    if (selected) {
      // 当选择时，将当前行添加到已选择的数据中
      state.selectedRowKeys = [
        ...new Set([record.id, ...state.selectedRowKeys]),
      ];
      state.selectedRows = [...new Set([record, ...state.selectedRows])];
    } else {
      // 当取消选择时，将当前行从已选择的数据中移除
      state.selectedRowKeys = state.selectedRowKeys.filter(
        (key) => key !== record.id,
      );
      state.selectedRows = state.selectedRows.filter(
        (row) => row.id !== record.id,
      );
    }
    // 更新Select的值
    state.selectValue = state.selectedRows.map((row) => row.id);
  },
});

/** 搜索 */
const handleSearch = async () => {
  // 获取数据
  fetchData();
};

// 当用户删除select中的值时，移除表格中的对应选中项
const handleSelectChange = (newSelectedValue: any) => {
  // 获取需要移除的行的key
  const keysToRemove = new Set(
    state.selectedRows
      .filter((row) => !newSelectedValue.includes(row.id))
      .map((row) => row.id),
  );

  // 从selectedRowKeys和selectedRows中移除相应的项
  state.selectedRowKeys = state.selectedRowKeys.filter(
    (key) => !keysToRemove.has(key),
  );
  state.selectedRows = state.selectedRows.filter(
    (row) => !keysToRemove.has(row.id),
  );

  // 更新Select的值
  state.selectValue = newSelectedValue;
};

onMounted(async () => {
  try {
    // 获取数据
    const { data, field_names } = useDatasourceStore().getdataSource(
      props.dataSource.api.toLowerCase(),
      props,
    );
    treeData.value = await data;
    fieldNames.value = field_names;
    pagination.value.total =
      treeData.value.length < pagination.value.pageSize
        ? pagination.value.pageSize - 1
        : pagination.value.pageSize + 1;
  } catch (error) {
    console.warn(
      `没有找到对应的方法，请检查${props.dataSource.api}是否有声明！`,
    );
    console.error(error);
  }
});
// 监听 props.value 的变化，自动更新 selectValue
watch(
  () => props.value, // 监听 props.value
  (newValue) => {
    selectValue.value = props.dataSource.multi
      ? convertToNumberArray(newValue)
      : newValue; // 当 props.value 发生变化时，更新 selectValue
    // 当props.dataSource.multi为true时去除为0的值
    if (props.dataSource.multi) {
      selectValue.value = selectValue.value.filter(
        (item: any) => item !== '' && item !== 0,
      );
    }
    state.selectedRowKeys = selectValue.value;
  },
  { deep: true }, // 开启深度监听
);

// 监听state.selectValue 的变化，自动更新 selectValue
watch(
  () => state.selectValue, // 监听 props.value
  (newValue) => {
    if (props.dataSource.multi)
      newValue = newValue.filter((item: any) => !isEmpty(item)); // 防止传入空数据
    emit('update:value', newValue); // 发射更新事件给父组件
  },
  { deep: true }, // 开启深度监听
);
</script>

<template>
  <div>
    <template v-if="api === 'portal/article/index'">
      <Select
        v-model:value="selectValue"
        :field-names="fieldNames"
        :options="treeData"
        :show-search="false"
        mode="multiple"
        placeholder="请选择"
        style="min-width: 500px"
        @change="handleSelectChange"
      >
        <template #dropdownRender>
          <InputSearch
            v-model:value="state.searchQuery"
            enter-button
            placeholder="搜索..."
            style="margin-bottom: 10px"
            @search="handleSearch"
          />
          <Table
            :columns="columns"
            :data-source="treeData"
            :pagination="pagination"
            :row-key="(record) => record.id"
            :row-selection="{
              selectedRowKeys: state.selectedRowKeys,
              onChange: rowSelection.onChange,
              onSelect: rowSelection.onSelect,
            }"
            size="small"
            @change="handleTableChange"
          />
        </template>
      </Select>
    </template>
    <template v-else>
      <TreeSelect
        v-bind="$attrs"
        :field-names="fieldNames"
        :max-tag-count="1"
        :multiple="dataSource.multi"
        :placeholder="placeholder"
        :tree-data="treeData"
        :value="selectValue"
        allow-clear
        style="min-width: 240px"
        tree-default-expand-all
        tree-node-filter-prop="label"
        @select="onSelect"
      />
    </template>
  </div>
</template>
